﻿using Lib.Data.Entitys;
using Lib.Data.Enumeration;
using System.Reflection;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using JavaScript = System.Text.Json.JsonSerializer;

namespace Lib.Data;
/// <summary>
/// 通用方法类
/// </summary>
internal static partial class Common {
    /// <summary>
    /// 
    /// </summary>
    static Common(){
        try {
            var Assembly = System.Reflection.Assembly.LoadFrom("Lib.MonitLogs.DLL");
            if (Assembly != null) {
                var Ins = Assembly.GetType("Lib.MonitLogs.Logs");
                if (Ins != null) {
                    Logs = Ins.GetMethod("Write", [typeof(string), typeof(string)]);
                }
            }
        } catch {

        }
        Opts = new JsonSerializerOptions() {
            // 处理中文转义问题（转义不安全字符） 
            Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
            // 不使用驼峰样式
            PropertyNamingPolicy = null,
            // 忽略循环引用
            ReferenceHandler = ReferenceHandler.IgnoreCycles,
            // 处理注释
            ReadCommentHandling = JsonCommentHandling.Skip,
            // 忽略大小写
            PropertyNameCaseInsensitive = true,
            // 是否缩进
            WriteIndented = false
        };
    }
    /// <summary>
    /// 
    /// </summary>
    internal static readonly MethodInfo Logs;
    /// <summary>
    /// 序列化选项
    /// </summary>
    internal static JsonSerializerOptions Opts { get; set; }
    /// <summary>
    /// 
    /// </summary>
    public static string Serialize(object Value) {
       return JavaScript.Serialize(Value, Opts);
    }
    /// <summary>
    /// 处理字段值序列化时转换
    /// </summary>
    internal static object ToValue(this object Value, Type e = null) {
        if (Value.IsEmpty()) {
            return "null";
        }
        if (e == null) {
            e = Value.GetType();
        }
        if (e.IsValueType) {
            switch (e.Name) {
                case "Boolean":
                    return (bool)Value ? 1 : 0;
                case "DateTime":
                    DateTime dt = (DateTime)Value;
                    if (dt == DateTime.MinValue) {
                        return "null";
                    }
                    return string.Concat("\"", dt.ToString("yyyy-MM-dd HH:mm:ss"), "\"");
                default:
                    return Value;
            }
        }
        if(e.IsClass && e.Name == "String") {
            if (Value.ToString() == string.Empty) {
                return "null";
            }
        }
        var Result = Value.ToString();
        if ((Result.StartsWith('[') && Result.EndsWith(']')) || (Result.StartsWith('{') && Result.EndsWith('}'))) {
            return Result;
        }
        return string.Concat("\"", Result, "\"");
    }
    /// <summary>
    /// 是否为空（Null、DBNull.Value）
    /// </summary>
    public static bool IsEmpty(this object Value) {
        if (Value == null || Value == DBNull.Value) {
            return true;
        }
        return false;
    }
    /// <summary>
    /// 检测是否为数字类型（包含枚举类型）
    /// </summary>
    public static bool IsNumber(object e) {
        if (e != null) {
            return e.GetType().IsNumber();
        }
        return false;
    }
    /// <summary>
    /// 检测是否为数字类型（包含枚举类型）
    /// </summary>
    public static bool IsNumber(this Type e) {
        if (!e.IsValueType) {
            return false;
        }
        return e.Name switch {
            "Char" or "Boolean" or "DateTime" or "Guid" => false,
            _ => true,
        };
    }

    #region "Boolean 布尔值"

    /// <summary>
    /// 转换成 Boolean 类型
    /// </summary>
    public static bool ToBoolean(this object Value, bool DefaultValue = false) {
        if ((!Convert.IsDBNull(Value) && !object.Equals(Value, null))) {
            return ToBoolean(Value.ToString(), DefaultValue);
        }
        return DefaultValue;
    }
    /// <summary>
    /// 转换成 Boolean 类型
    /// </summary>
    public static bool ToBoolean(this string Value, bool DefaultValue = false) {
        if (string.IsNullOrEmpty(Value)) {
            return DefaultValue;
        }
        Value = Value.Trim();
        if (((string.Compare(Value, "true", StringComparison.OrdinalIgnoreCase) == 0) || ((string.Compare(Value, "yes", StringComparison.OrdinalIgnoreCase) == 0) || (string.Compare(Value, "1", StringComparison.OrdinalIgnoreCase) == 0)))) {
            return true;
        }
        return false;
    }

    #endregion

    #region "Integer 32位有符号的整数"

    /// <summary>
    /// 转换成 Integer(Int32) 类型(32位有符号的整数)
    /// </summary>
    public static int ToInt32(this object Value, int DefaultValue = 0) {
        if ((!Convert.IsDBNull(Value) && !object.Equals(Value, null))) {
            return ToInt32(Value.ToString(), DefaultValue);
        }
        return DefaultValue;
    }
    /// <summary>
    /// 转换成 Integer(Int32) 类型(32位有符号的整数)
    /// </summary>
    public static int ToInt32(this string Value, int defaultValue = 0) {
        if (!int.TryParse(Value, out int Index)) {
            Index = defaultValue;
        }
        return Index;
    }

    #endregion

    #region "Long 64位有符号的整数"

    /// <summary>
    /// 转换成 Long(Int64) 类型(64位有符号的整数)
    /// </summary>
    public static long ToInt64(this object Value, long DefaultValue = 0) {
        if ((!Convert.IsDBNull(Value) && !object.Equals(Value, null))) {
            return ToInt64(Value.ToString(), DefaultValue);
        }
        return DefaultValue;
    }
    /// <summary>
    /// 转换成 Long(Int64) 类型(64位有符号的整数)
    /// </summary>
    public static long ToInt64(this string Value, long defaultValue = 0) {
        if (!Int64.TryParse(Value, out long Index)) {
            Index = defaultValue;
        }
        return Index;
    }

    #endregion

    /// <summary>
    /// 写日志
    /// </summary>
    internal static void WriteLog(string Content, string Key) {
        Logs?.Invoke(null, [Content, Key]);
    }

    [GeneratedRegex(@"(T)([0-9]?\d:[0-5]?\d:[0-5]?\d)", RegexOptions.IgnoreCase | RegexOptions.Compiled, "zh-CN")]
    private static partial Regex DateRegEx();
    /// <summary>
    /// 格式化时间 2019-12-08T00:28:39 转 2019-12-08 00:28:39
    /// </summary>
    public static string FormatDateTime(string dt) {
        MatchCollection MM = DateRegEx().Matches(dt);
        foreach (Match M in MM) {
            dt = dt.Replace(M.Value, " " + M.Groups[2].Value);
        }
        return dt;
    }
    /// <summary>
    /// 
    /// </summary>
    internal static object Deserialize(object Value, Type Type) {
        try {
            if(Value == null) {
                return null;
            }
            var JSon = Value.ToString();
            if((JSon.StartsWith('{') && JSon.EndsWith('}'))||(JSon.StartsWith('[') && JSon.EndsWith(']'))) {
                return JavaScript.Deserialize(JSon, Type);
            }
        } catch { 
        
        }
        return null;
    }
    /// <summary>
    /// 解析字段列
    /// </summary>
    internal static Parts Parse(string Columns) {
        var e = Parts.Create;
        if (Columns.StartsWith('@')) {
            e.Keys = Columns.TrimStart('@').TrimStart(',').Split(',');
            e.Ignore = true;
        } else {
            foreach (var Key in Columns.Split(',')) {
                var Value = Key.Trim();
                string[] Keys;
                if (Value.Contains(".As.")) {
                    Keys = Value.Split('.');
                    e.Keys.Add(Keys[2]);
                    e.Alias.Add(Keys[0], Keys[2]);
                } else if (Value.Contains(':')) {
                    Keys = Value.Split(':');
                    e.Keys.Add(Keys[1]);
                    e.Alias.Add(Keys[0], Keys[1]);
                } else {
                    e.Keys.Add(Value);
                }
            }
        }
        return e;
    }
    /// <summary>
    /// 
    /// </summary>
    internal static PropertyType GetPropertyType(this Type e) {
        if (e.IsValueType || e.Name == "String") {
            if (e.IsEnum) {
                return PropertyType.EnumType;
            }
            return PropertyType.PrimitiveType;
        }
        if (e.IsClass) {
            if (e.IsArray) {
                return PropertyType.ArrayType;
            }
            if (e.FullName.StartsWith("System.Collections.")) {
                return PropertyType.CollectionType;
            }
        }
        if (e.IsInterface) {
            if (e.FullName.StartsWith("System.Collections.") || e.Name == "IHeaderDictionary") {
                return PropertyType.CollectionType;
            }
        }
        return PropertyType.EntityType;
    }
    /// <summary>
    /// 
    /// </summary>
    internal static DataType GetDataType(this Type e) {
        if (e.IsValueType) {
            if (e.IsEnum) {
                return DataType.Enum;
            }
            switch (e.Name) {
                case "Double":
                case "Single":
                case "Decimal":
                    return DataType.Float;
                case "Boolean":
                    return DataType.Boolean;
                case "DateTime":
                    return DataType.DateTime;
                case "Guid":
                    return DataType.GUID;
                case "Char":
                    return DataType.String;
                default:
                    break;
            }
            return DataType.Int;
        }
        if (e.Name == "String") {
            return DataType.String;
        }
        return DataType.Object;
    }
    /// <summary>
    /// 改变类型
    /// </summary>
    internal static T ChanageType<T>(this object Value) {
        if (Value == null || Value is DBNull) {
            return default;
        }
        var ObjectType = typeof(T);
        if (ObjectType.Equals(Value.GetType())) {
            return (T)Value;
        }
        if (ObjectType.IsGenericType) {
            var RawType = Nullable.GetUnderlyingType(ObjectType);
            if (RawType != null) {
                return (T)Convert.ChangeType(Value, RawType);
            }
        }
        return (T)Convert.ChangeType(Value, ObjectType);
    }
    /// <summary>
    /// 生成数据库连接字符串关键字
    /// </summary>
    internal static string ConnectKey(this dbType dbType, string ConnectString) {
        return dbType switch {
            dbType.Excel or dbType.Access or dbType.SQLite or dbType.Text => $"db.{dbType}",
            _ => $"db.{dbType}.{ConnectString.GetHashCode().ToString().Replace("-", "D")}",
        };
    }
    /// <summary>
    /// 
    /// </summary>
    internal static string Key(this Type Type) {
        return string.Concat(Type.Namespace, ".", Type.Name);
    }

}